import inherits from 'inherits';
import BaseRenderer from 'diagram-js/lib/draw/BaseRenderer';
import { append as svgAppend, create as svgCreate, classes as svgClasses } from 'tiny-svg';
import EventBus from 'diagram-js/lib/core/EventBus';
import serialBranch from '../../../assets/images/serialBranch.svg';
import parallelBranch from '../../../assets/images/parallelBranch.svg';
import includeBranch from '../../../assets/images/includeBranch.svg';
import { customConfig, firstTaskId, getSvg } from '../../utils';

export default function CustomRenderer(
  this: any,
  eventBus: EventBus,
  canvas: any,
  modeling: any,
) {
  BaseRenderer.call(this, eventBus, 2000);
  this.drawElements = function (parentNode: any, element: { type: any, labels: any }) {
    return drawCustomElements(parentNode, element, canvas, modeling, { instance: this });
  };
}

inherits(CustomRenderer, BaseRenderer);

CustomRenderer.$inject = ['eventBus', 'canvas', 'modeling'];

CustomRenderer.prototype.canRender = function (element: any) {
  return true;
  // return element.type != 'label';
  // return !element.labelTarget;
};

CustomRenderer.prototype.drawShape = function (parentNode: any, element: any) {
  return this.drawElements(parentNode, element);
};

function drawCustomElements(parentNode: Element, element: { [x: string]: any; type?: any }, canvas: { getGraphics: (arg0: { [x: string]: any; type?: any; }) => any; }, modeling: any, instance: any) {
  let shearIdsArray: string[] = [];
  if (instance?.instance?.shearCache && instance?.instance?.shearCache?.length > 0) {
    shearIdsArray = [...instance?.instance?.shearCache];
  };
  let _svg = canvas.getGraphics(element);
  let _ifCreated: boolean = false;
  let _isPasted: boolean = false;
  if (_svg) {
    _ifCreated = svgClasses(_svg).list.value?.includes('element-created');
  };
  if (element?.id?.startsWith('Activity') || element?.id?.startsWith('Gateway') || shearIdsArray?.length > 0 && shearIdsArray?.includes(element?.id)) {
    _isPasted = true;
    _ifCreated = true;
  };
  const bpmnForView = instance?.instance?.bpmnForView;
  const { type, id } = element;
  const isCurrentNode = instance?.instance?.activities?.includes(id);
  const { attr } = customConfig[type];
  if (element?.type == 'label') {
    const _parentNode = parentNode?.parentNode?.parentNode;
    // @ts-ignore
    svgClasses(_parentNode).add('svg-label');
  };
  const isCurrentViewElement = instance?.instance?.currentNodeId == element?.id;
  const isCurrentHoverViewElement = instance?.instance?.hoverNodeId == element?.id;
  const isReturnBackViewElement = instance?.instance?.returnBackNodeIds?.includes(element?.id);
  switch (type) {
    case 'bpmn:UserTask':
    case 'bpmn:CallActivity':
      const customElement = svgCreate('rect', {
        rx: 9,
        tx: 9,
        stroke: isReturnBackViewElement ? '#ff1313' : isCurrentNode ? 'rgb(61, 200, 133)' : '#ffffff',
        strokeWidth: isCurrentNode ? 4 : 1,
        width: 100,
        height: 60,
        x: 0,
        y: 0,
        fill: 'rgb(255, 255, 255)',
      });
      svgAppend(parentNode, customElement);
      if (_ifCreated || id == firstTaskId || bpmnForView === true) {
        getSvg(parentNode, element, isCurrentViewElement, isCurrentNode, isCurrentHoverViewElement, isReturnBackViewElement);
      };
      return customElement;
    case 'bpmn:StartEvent':
      const customStartEventIcon = svgCreate('circle', {
        r: 15,
        stroke: 'rgb(215, 218, 229)',
        strokeWidth: 1,
        cx: 15,
        cy: 15,
        fill: '#71b771',
        class: 'bpmnElementStartEventCustomElementType',
      });
      svgAppend(parentNode, customStartEventIcon);
      return customStartEventIcon;
    case 'bpmn:EndEvent':
      const customEndEventIcon = svgCreate('circle', {
        r: 15,
        stroke: 'rgb(215, 218, 229)',
        strokeWidth: 1,
        // cx: (_ifCreated || bpmnForView === true) ? 15 : 9,
        // cy: (_ifCreated || bpmnForView === true) ? 15 : 9,
        cx: 15,
        cy: 15,
        fill: '#ec705f',
        class: 'bpmnElementEndEventCustomElementType',
      });
      svgAppend(parentNode, customEndEventIcon);
      return customEndEventIcon;
    case 'bpmn:ExclusiveGateway':
      const exclusiveGatewaycustomIcon = svgCreate('image', {
        ...attr,
        href: serialBranch,
        x: 0,
        y: _isPasted ? 0.5 : 0,
      });
      svgAppend(parentNode, exclusiveGatewaycustomIcon);
      return exclusiveGatewaycustomIcon;
    case 'bpmn:ParallelGateway':
      const inclusiveGatewayCustomIcon = svgCreate('image', {
        ...attr,
        href: parallelBranch,
        x: 0,
        y: _isPasted ? 0.5 : 0,
      });
      svgAppend(parentNode, inclusiveGatewayCustomIcon);
      return inclusiveGatewayCustomIcon;
    case 'bpmn:InclusiveGateway':
      const activityCustomIcon = svgCreate('image', {
        ...attr,
        href: includeBranch,
        x: 0,
        y: _isPasted ? 0.5 : 0,
      });
      svgAppend(parentNode, activityCustomIcon);
      return activityCustomIcon;
    default:
      break;
  }
};